<html>
  <script>
    var currentSite = null;
    var currentTabId = null;
    var startTime = null;
    var siteRegexp = /^(\w+:\/\/[^\/]+).*$/;

    var updateCounterInterval = 1000 * 60;  // 1 minute.

    var trackerServer = "http://browser-timetracker.appspot.com";

    var lastActivitySeconds = 0;

    /**
     * Returns just the site/domain from the url. Includes the protocol.
     * chrome://extensions/some/other?blah=ffdf -> chrome://extensions
     * @param {string} url The URL of the page, including the protocol.
     * @return {string} The site, including protocol, but not paths.
     */
    function getSiteFromUrl(url) {
      var match = url.match(siteRegexp);
      if (match) {
        return match[1];
      }
      return null;
    }

    function checkIdleTime() {
      lastActivitySeconds += 10;
      if (localStorage["paused"] == "false" && lastActivitySeconds > 60) {
        console.log("Idle for " + lastActivitySeconds + " seconds.");
        pause();
      }
    }

    function pause() {
      localStorage["paused"] = "true";
      chrome.browserAction.setIcon({path: 'images/icon_paused.png'});
    }

    function resume() {
      localStorage["paused"] = "false";
      chrome.browserAction.setIcon({path: 'images/icon.png'});
    }

    /**
     * This should be called whenever activity by the user is detected.
     */
    function resetActivity() {
      lastActivitySeconds = 0;
      if (localStorage["paused"] == "true") {
        resume();
      }
    }

    /**
     * Updates the counter for the current tab.
     */
    function updateCounter() {
      /* Don't run if we are paused. */
      if (localStorage["paused"] == "true") {
        currentSite = null;
        return;
      }

      if (currentTabId == null) {
        return;
      }

      chrome.tabs.get(currentTabId, function(tab) {
        /* Make sure we're on the focused window, otherwise we're recording bogus stats. */
        chrome.windows.get(tab.windowId, function(window) {
          if (!window.focused) {
            return;
          }
          var site = getSiteFromUrl(tab.url);
          if (site == null) {
            console.log("Unable to update counter. Malformed url.");
            return;
          }

          /* We can't update any counters if this is the first time visiting any
           * site. This happens on browser startup. Initialize some variables so
           * we can perform an update next time. */
          if (currentSite == null) {
            currentSite = site;
            startTime = new Date();
            return;
          }

          /* Update the time spent for this site by comparing the current time to
           * the last time we were ran. */
          var now = new Date();
          var delta = now.getTime() - startTime.getTime();
          updateTime(currentSite, delta/1000);

          /* This function could have been called as the result of a tab change,
           * which means the site may have changed. */
          currentSite = site;
          startTime = now;
        });
      });
    }

    /**
     * Clears all statistics stored on server.
     */
     function clearStatistics() {
       if (localStorage["storageType"] == "appengine") {
         var xhr = new XMLHttpRequest();
         xhr.open(
           "GET", trackerServer + "/stats/clear", false);
         xhr.send(null);
       }
       localStorage.sites = JSON.stringify({});
     }

    /**
     * Sends statistics to the server. If there are no problems in sending the
     * data, we clear local storage. */
     function sendStatistics() {
       if (localStorage["paused"] == "true") {
         console.log("Paused, not sending statistics.");
         return;
       }

       console.log("Sending statistics.");
       if (localStorage["storageType"] == "appengine") {
         console.log("Sending stats to server.");
         sendStatisticsToServer();
       } else {
         console.log("Warning: Unsupported storage type.");
       }
     }

     function sendStatisticsToServer() {
      var xhr = new XMLHttpRequest();
      var params = "sites=" + escape(localStorage.sites) +
                   "&now=" + escape(new Date().getTime()/1000);
      xhr.open("POST", trackerServer + "/stats/update", false);
      xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      try {
        xhr.send(params);
      } catch (e) {
        console.log("Exception when sending stats to server.");
        chrome.browserAction.setIcon({path: 'images/icon_error.png'});
        return;
      }
      chrome.browserAction.setIcon({path: 'images/icon.png'});
      if (xhr.status == 200) {
        console.log("Successfully updated statistics.");
        localStorage.sites = JSON.stringify({});
      } else {
        console.log("Something went wrong with updating stats: " + xhr.status);
      }
    }

    /**
     * Updates the amount of time we have spent on a given site.
     * @param {string} site The site to update.
     * @param {float} seconds The number of seconds to add to the counter.
     */
    function updateTime(site, seconds) {
      var sites = JSON.parse(localStorage.sites);
      if (!sites[site]) {
        sites[site] = 0;
      }
      sites[site] = sites[site] + seconds;
      localStorage.sites = JSON.stringify(sites);
    }

    /**
     * Initailized our storage and sets up tab listeners.
     */
    function initialize() {
      if (!localStorage.sites) {
        localStorage.sites = JSON.stringify({});
      }

      if (localStorage["paused"] == "true") {
        pause();
      }

      /* Add some listeners for tab changing events. We want to update our
      *  counters when this sort of stuff happens. */
      chrome.tabs.onSelectionChanged.addListener(
      function(tabId, selectionInfo) {
        console.log("Tab changed");
        resetActivity();
        currentTabId = tabId;
        updateCounter();
      });

      chrome.tabs.onUpdated.addListener(
      function(tabId, changeInfo, tab) {
        if (tabId == currentTabId) {
          console.log("Tab updated");
          updateCounter();
        }
      });

      chrome.windows.onFocusChanged.addListener(
      function(windowId) {
        console.log("Detected window focus changed.");
        resetActivity();
        chrome.tabs.getSelected(windowId,
        function(tab) {
          console.log("Window/Tab changed");
          currentTabId = tab.id;
          updateCounter();
        });
      });

      chrome.browserAction.onClicked.addListener(function(tab) {
        sendStatistics();
      });

      /* Listen for update requests. These come from the popup. */
      chrome.extension.onRequest.addListener(
        function(request, sender, sendResponse) {
          if (request.action == "sendStats") {
            console.log("Sending statistics by request.");
            sendStatistics();
            sendResponse({});
          } else if (request.action == "clearStats") {
            console.log("Clearing statistics by request.");
            clearStatistics();
            sendResponse({});
          } else if (request.action == "pause") {
            pause();
          } else if (request.action == "resume") {
            resume();
          } else {
            console.log("Invalid action given.");
          }
        });

        chrome.extension.onConnect.addListener(function(port) {
          console.assert(port.name == "idle");
          port.onMessage.addListener(function(msg) {
            resetActivity();
          });
        });

      /* Force an update of the counter every minute. Otherwise, the counter
         only updates for selection or URL changes. */
      window.setInterval(updateCounter, updateCounterInterval);

      if (!localStorage["sendStatsInterval"]) {
        localStorage["sendStatsInterval"] = 3600 * 1000;
      }

      /* Default is to use local only storage. */
      // if (!localStorage["storageType"]) {
      //  localStorage["storageType"] = "local";
      // }
      localStorage["storageType"] = "local";

      // Send statistics periodically.
      console.log("Sending stats interval " + localStorage["sendStatsInterval"]);
      window.setInterval(sendStatistics, localStorage["sendStatsInterval"]);

      // Keep track of idle time.
      window.setInterval(checkIdleTime, 10 * 1000);
    }

  </script>
  <body onload="initialize()">
  </body>
</html>
